/**
 * 文件名：@MonitorInterceptor.java <br/>
 * 包名：cn.efunbox.afw.web.mvc.interceptor <br/>
 * 项目名：afw-web <br/>
 * @author xtwin <br/>
 */
package cn.efunbox.afw.web.mvc.interceptor;

import java.util.concurrent.Semaphore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import cn.efunbox.afw.core.exception.SystemException;

/**
 * 类名：MonitorInterceptor  <br />
 *
 * 功能：线程数量监控
 *
 * @author xtwin <br />
 * 创建时间：2015年12月8日 下午2:23:09  <br />
 * @version 2015年12月8日
 */
public class MonitorInterceptor extends HandlerInterceptorAdapter {
	
	// 最大运行线程数量
	private int maxActive = -1;
	
	// 最大等待数量
	private int maxWait = 20;
	
	// 信号量
	private Semaphore semaphore;
	
	// 是否采用公平竞争机制，公平竞争将导致效率降低，默认为非公平
	private boolean fair;
	
	/**
	 * 
	 * 功能：初始化 <br/>
	 *
	 * @author xtwin <br/>
	 * @version 2015年12月8日 下午2:26:55 <br/>
	 */
	public void init() {
		if (maxActive > 0) {
			semaphore = new Semaphore(maxActive, fair);
		}
	}
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015年12月8日 下午2:32:37<br/>
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @return
	 * @throws Exception <br/>
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
	 */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		if (maxActive > 0) {
			if (semaphore.getQueueLength() < maxWait) {
				/**
				 * 申请令牌，若当前令牌已使用完毕，当前线程将在此阻塞
				 */
				semaphore.acquire();
			} else {
				throw new SystemException("system.error.is.busy");
			}
		}
		
		return true;
	}
	
	/**
	 * 功能: <br/>
	 * 
	 * 重写：xtwin <br/>
	 * 
	 * @version ：2015年12月8日 下午2:33:03<br/>
	 * 
	 * @param request
	 * @param response
	 * @param handler
	 * @param ex
	 * @throws Exception <br/>
	 * @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		if (maxActive > 0) {
			// 释放令牌
			semaphore.release();
		}
	}

	/**
	 * @version 2015年12月8日-下午2:43:57
	 */
	public void setMaxActive(int maxActive) {
		this.maxActive = maxActive;
	}

	/**
	 * @version 2015年12月8日-下午2:43:57
	 */
	public void setMaxWait(int maxWait) {
		this.maxWait = maxWait;
	}

	/**
	 * @version 2015年12月8日-下午2:43:57
	 */
	public void setSemaphore(Semaphore semaphore) {
		this.semaphore = semaphore;
	}

	/**
	 * @version 2015年12月8日-下午2:43:57
	 */
	public void setFair(boolean fair) {
		this.fair = fair;
	}
}